﻿using Admin.NET.Core.Service;
using Admin.NET.Application.Const;
using Admin.NET.Application.Entity;
using Microsoft.AspNetCore.Http;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Furion.DatabaseAccessor;
namespace Admin.NET.Application;
/// <summary>
/// 选课任务服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class XuankeTaskService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<XuankeTask> _rep;
    private readonly SqlSugarRepository<Student> _stuRep;
    private readonly SqlSugarRepository<XuanKe> _xuankeRep;
    private readonly SqlSugarRepository<SysFile> _fileRep;
    private readonly SqlSugarRepository<Kecheng> _kcRep;

    public XuankeTaskService(SqlSugarRepository<XuankeTask> rep, SqlSugarRepository<Student> stuRep, SqlSugarRepository<XuanKe> xuankeRep, SqlSugarRepository<SysFile> fileRep, SqlSugarRepository<Kecheng> kcRep)
    {
        _rep = rep;
        _stuRep = stuRep;
        _xuankeRep = xuankeRep;
        _fileRep = fileRep;
        _kcRep = kcRep;
    }

    /// <summary>
    /// 分页查询选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    public async Task<SqlSugarPagedList<XuankeTaskOutput>> Page(XuankeTaskInput input)
    {
        var query = _rep.AsQueryable()
            .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
                u.Name.Contains(input.SearchKey.Trim())
                || u.Status.Contains(input.SearchKey.Trim())
                || u.Remark.Contains(input.SearchKey.Trim())
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
            .WhereIF(input.Ji>0, u => u.Ji == input.Ji)
            .WhereIF(input.Active>=0, u => u.Active == (input.Active.Value == 1))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Status), u => u.Status.Contains(input.Status.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim()))
            .OrderByDescending(u => u.Id)
            .Select<XuankeTaskOutput>();
        if(input.StartTimeRange != null && input.StartTimeRange.Count >0)
        {
            DateTime? start= input.StartTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.StartTime > start);
            if (input.StartTimeRange.Count >1 && input.StartTimeRange[1].HasValue)
            {
                var end = input.StartTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.StartTime < end);
            }
        } 
        if(input.EndTimeRange != null && input.EndTimeRange.Count >0)
        {
            DateTime? start= input.EndTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.EndTime > start);
            if (input.EndTimeRange.Count >1 && input.EndTimeRange[1].HasValue)
            {
                var end = input.EndTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.EndTime < end);
            }
        } 
        return await query.ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 增加选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    public async Task<long> Add(AddXuankeTaskInput input)
    {
        var entity = input.Adapt<XuankeTask>();
        await _rep.InsertAsync(entity);
        return entity.Id;
    }

    /// <summary>
    /// 删除选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    public async Task Delete(DeleteXuankeTaskInput input)
    {
        var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        //await _rep.FakeDeleteAsync(entity);   //假删除
        await _rep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    public async Task Update(UpdateXuankeTaskInput input)
    {
        var entity = input.Adapt<XuankeTask>();
        await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    public async Task<XuankeTask> Detail([FromQuery] QueryByIdXuankeTaskInput input)
    {
        return await _rep.GetFirstAsync(u => u.Id == input.Id);
    }

    /// <summary>
    /// 初始化选课任务
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Init")]
    public async Task Init(DeleteXuankeTaskInput input)
    {
        var task = await _rep.GetByIdAsync(input.Id);
        var list = await _stuRep.AsQueryable()
            .LeftJoin<JiaoxueBan>((s, j) => s.JiaoxueBanId == j.Id)
            .Where((s, j) => s.BeAtSchool == true && j.IsGraduated == false && j.Ji == task.Ji && s.IsTuoguan == true).ToListAsync();
        foreach (var stu in list)
        {
            var xuanke = await _xuankeRep.AsQueryable().Where(p => p.XuankeTaskId == input.Id && p.StudentId == stu.Id).FirstAsync();
            if (xuanke == null)
            {
                xuanke = new XuanKe();
                xuanke.XuankeTaskId = input.Id;
                xuanke.BanjiId = stu.BanjiId;
                xuanke.JiaoxueBanId = stu.JiaoxueBanId;
                xuanke.StudentId = stu.Id;
                xuanke.IsYuxuan = false;
                await _xuankeRep.InsertAsync(xuanke);
            }
        }
    }

    /// <summary>
    /// 导入预选名单
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [UnitOfWork]
    [ApiDescriptionSettings(Name = "Import")]
    public async Task<string> Import(ImportXuankeTaskInput input)
    {
        var strRtn = string.Empty;
        var task = await _rep.GetByIdAsync(input.XuankeTaskId);
        var file = _fileRep.GetById(input.FileId);
        var filePath = App.WebHostEnvironment.WebRootPath;
        filePath = System.IO.Path.Combine(filePath, file.FilePath);
        filePath = System.IO.Path.Combine(filePath, file.Id.ToString());
        filePath += file.Suffix;

        IImporter importer = new ExcelImporter();
        var res = await importer.Import<XuanKeImportDto>(filePath);
        foreach (var item in res.Data)
        {
            Student student = null;
            if(item.StudentIdXh.IsNullOrEmpty() == false)
                student = await _stuRep.AsQueryable().Where(p => p.Xh == item.StudentIdXh).FirstAsync();
            else
            {
                student = await _stuRep.AsQueryable()
                    .LeftJoin<JiaoxueBan>((s,j)=>s.JiaoxueBanId==j.Id)
                    .Where((s,j) => s.Name == item.StudentIdName && j.Ji == task.Ji)
                    .FirstAsync();
            }
            if(student != null)
            {
                var xuanke = await _xuankeRep.AsQueryable().Where(p => p.XuankeTaskId == task.Id && p.StudentId == student.Id).FirstAsync();
                var kc = await _kcRep.AsQueryable().Where(p => p.XuankeTaskId == task.Id && p.Name == item.KechengIdName).FirstAsync();
                if (student != null && xuanke != null && kc != null)
                {
                    xuanke.KechengId = kc.Id;
                    xuanke.IsYuxuan = true;
                    await _xuankeRep.UpdateAsync(xuanke);
                }
                else
                {
                    if(xuanke == null)
                    {
                        strRtn += string.Format("选课名单中找不到学生{0}<br />", item.StudentIdName);
                    }
                    if (kc == null)
                    {
                        strRtn += string.Format("课程名单中找不到{0}<br />", item.KechengIdName);
                    }
                }
            }
            else
            {
                strRtn += string.Format("学生名单中找不到{0}<br />", item.StudentIdName);
            }
        }
        var list = await _kcRep.AsQueryable().Where(p => p.XuankeTaskId == task.Id).ToListAsync();
        foreach ( var kc in list )
        {
            kc.LvquRenshu = await _xuankeRep.AsQueryable().Where(p=>p.XuankeTaskId == task.Id && p.KechengId == kc.Id).CountAsync();
            await _kcRep.UpdateAsync(kc);
        }
        return strRtn;
    }
    
}

